<?php
/**
 * 职位服务层
 *
 * @author Claude Code
 * @since 2025-11-03
 */

namespace app\service;

use app\model\admin\Position;
use app\model\admin\User;
use think\facade\Db;
use think\exception\ValidateException;

/**
 * 职位业务逻辑处理
 *
 * 主要职责：
 * 1. 职位数据的增删改查
 * 2. 职位层级管理
 * 3. 职位员工统计
 * 4. 缓存管理
 */
class PositionService extends BaseService
{
    /**
     * 职位模型
     * @var Position
     */
    protected $positionModel;

    /**
     * 用户模型
     * @var User
     */
    protected $userModel;

    /**
     * 缓存键前缀
     */
    protected const CACHE_PREFIX = 'position:';

    /**
     * 缓存过期时间
     */
    protected const CACHE_EXPIRE = 3600;

    /**
     * 构造函数
     */
    public function __construct()
    {
        $this->positionModel = new Position();
        $this->userModel = new User();

        $this->setModel($this->positionModel);
        $this->setCacheConfig(true, self::CACHE_PREFIX, self::CACHE_EXPIRE);
    }

    /**
     * 获取职位列表
     * @param array $params 查询参数
     * @param bool $useCache 是否使用缓存
     * @return array
     */
    public function getPositionList(array $params = [], bool $useCache = true): array
    {
        $cacheKey = 'list:' . md5(serialize($params));

        if ($useCache) {
            $cached = $this->getCache($cacheKey);
            if ($cached !== null) {
                $this->logInfo('从缓存获取职位列表', ['params' => $params]);
                return $cached;
            }
        }

        // 使用模型的getList方法
        $result = $this->positionModel->getList($params);

        if ($useCache) {
            $this->setCache($cacheKey, $result);
        }

        $this->logInfo('获取职位列表成功', [
            'count' => count($result['list'] ?? [])
        ]);

        return $result;
    }

    /**
     * 获取职位详情
     * @param int $id 职位ID
     * @param bool $useCache 是否使用缓存
     * @return array|null
     */
    public function getPositionInfo(int $id, bool $useCache = true): ?array
    {
        if ($id <= 0) {
            return null;
        }

        $cacheKey = "info:{$id}";

        if ($useCache) {
            $cached = $this->getCache($cacheKey);
            if ($cached !== null) {
                return $cached;
            }
        }

        $position = $this->positionModel->find($id);

        if (!$position) {
            return null;
        }

        $positionData = $position->toArray();

        // 统计使用该职位的员工数量
        $positionData['user_count'] = Db::name('admin')
            ->where('position_id', $id)
            ->where('status', '>=', 0)
            ->count();

        // 获取使用该职位的员工列表（前10个）
        $users = Db::name('admin')
            ->field('id, name, username, did')
            ->where('position_id', $id)
            ->where('status', '>=', 0)
            ->limit(10)
            ->select()
            ->toArray();

        $positionData['users'] = $users;

        if ($useCache) {
            $this->setCache($cacheKey, $positionData);
        }

        return $positionData;
    }

    /**
     * 创建职位
     * @param array $data 职位数据
     * @return int 职位ID
     * @throws ValidateException
     */
    public function createPosition(array $data): int
    {
        // 数据验证
        $this->validatePositionData($data);

        // 检查职位名称是否已存在
        $existing = Db::name('position')
            ->where('title', $data['title'])
            ->where('status', '>', 0)
            ->find();

        if ($existing) {
            throw new ValidateException('职位名称已存在');
        }

        return $this->transaction(function () use ($data) {
            $positionData = [
                'title' => $data['title'],
                'work_price' => (int)($data['work_price'] ?? 0),
                'remark' => $data['remark'] ?? '',
                'status' => (int)($data['status'] ?? 1),
                'create_time' => time(),
                'update_time' => time()
            ];

            $positionId = Db::name('position')->insertGetId($positionData);

            // 清除相关缓存
            $this->clearPositionCache();

            $this->logInfo('创建职位成功', ['position_id' => $positionId, 'title' => $data['title']]);

            return $positionId;
        });
    }

    /**
     * 更新职位
     * @param int $id 职位ID
     * @param array $data 职位数据
     * @return bool
     * @throws ValidateException
     */
    public function updatePosition(int $id, array $data): bool
    {
        if ($id <= 0) {
            throw new ValidateException('职位ID不能为空');
        }

        // 检查职位是否存在
        $position = $this->positionModel->find($id);
        if (!$position) {
            throw new ValidateException('职位不存在');
        }

        // 数据验证
        $this->validatePositionData($data, $id);

        // 检查职位名称是否已存在（排除当前职位）
        if (isset($data['title'])) {
            $existing = Db::name('position')
                ->where('title', $data['title'])
                ->where('id', '<>', $id)
                ->where('status', '>', 0)
                ->find();

            if ($existing) {
                throw new ValidateException('职位名称已存在');
            }
        }

        return $this->transaction(function () use ($id, $data, $position) {
            $updateData = [
                'title' => $data['title'] ?? $position->title,
                'work_price' => (int)($data['work_price'] ?? $position->work_price),
                'remark' => $data['remark'] ?? $position->remark,
                'status' => (int)($data['status'] ?? $position->status),
                'update_time' => time()
            ];

            $result = Db::name('position')->where('id', $id)->update($updateData) > 0;

            // 清除相关缓存
            $this->clearPositionCache();

            $this->logInfo('更新职位成功', ['position_id' => $id]);

            return $result;
        });
    }

    /**
     * 删除职位（软删除）
     * @param int $id 职位ID
     * @return bool
     * @throws ValidateException
     */
    public function deletePosition(int $id): bool
    {
        if ($id <= 0) {
            throw new ValidateException('职位ID不能为空');
        }

        // 检查职位是否存在
        $position = $this->positionModel->find($id);
        if (!$position) {
            throw new ValidateException('职位不存在');
        }

        // 检查是否有员工使用该职位
        $userCount = Db::name('admin')
            ->where('position_id', $id)
            ->where('status', '>=', 0)
            ->count();

        if ($userCount > 0) {
            throw new ValidateException("该职位下有{$userCount}名员工，不能删除");
        }

        return $this->transaction(function () use ($id) {
            $result = Db::name('position')
                ->where('id', $id)
                ->update([
                    'status' => -1,
                    'update_time' => time()
                ]) > 0;

            // 清除相关缓存
            $this->clearPositionCache();

            $this->logInfo('删除职位成功', ['position_id' => $id]);

            return $result;
        });
    }

    /**
     * 验证职位数据
     * @param array $data 数据
     * @param int|null $id 职位ID（更新时）
     * @return void
     * @throws ValidateException
     */
    protected function validatePositionData(array $data, ?int $id = null): void
    {
        if (empty($data['title'])) {
            throw new ValidateException('职位名称不能为空');
        }

        $titleLength = mb_strlen($data['title']);
        if ($titleLength < 2) {
            throw new ValidateException('职位名称不能少于2个字符');
        }

        if ($titleLength > 50) {
            throw new ValidateException('职位名称不能超过50个字符');
        }

        if (isset($data['work_price']) && $data['work_price'] < 0) {
            throw new ValidateException('工价不能为负数');
        }
    }

    /**
     * 清除职位相关缓存
     * @return void
     */
    protected function clearPositionCache(): void
    {
        $this->clearCache('position');
    }

    /**
     * 获取启用的职位列表（用于下拉选择）
     * @return array
     */
    public function getActivePositions(): array
    {
        $cacheKey = 'active';

        $cached = $this->getCache($cacheKey);
        if ($cached !== null) {
            return $cached;
        }

        $positions = Db::name('position')
            ->field('id, title, work_price, remark')
            ->where('status', 1)
            ->order('id', 'asc')
            ->select()
            ->toArray();

        $this->setCache($cacheKey, $positions);

        return $positions;
    }

    /**
     * 根据ID获取职位信息
     * @param int $id 职位ID
     * @return array|null
     */
    public function getPositionById(int $id): ?array
    {
        if ($id <= 0) {
            return null;
        }

        $position = Db::name('position')
            ->where('id', $id)
            ->where('status', '>', 0)
            ->find();

        return $position ?: null;
    }

    /**
     * 批量更新职位状态
     * @param array $ids 职位ID数组
     * @param int $status 状态
     * @return int 更新数量
     */
    public function batchUpdateStatus(array $ids, int $status): int
    {
        if (empty($ids)) {
            return 0;
        }

        $updateCount = Db::name('position')
            ->where('id', 'in', $ids)
            ->update([
                'status' => $status,
                'update_time' => time()
            ]);

        if ($updateCount) {
            $this->clearPositionCache();
            $this->logInfo('批量更新职位状态成功', [
                'ids' => $ids,
                'status' => $status,
                'count' => $updateCount
            ]);
        }

        return $updateCount;
    }

    /**
     * 搜索职位
     * @param string $keyword 关键词
     * @param int $limit 限制数量
     * @return array
     */
    public function searchPositions(string $keyword, int $limit = 20): array
    {
        if (empty($keyword)) {
            return [];
        }

        $positions = Db::name('position')
            ->field('id, title, work_price, remark, status')
            ->where('status', '>', 0)
            ->where('title', 'like', '%' . $keyword . '%')
            ->limit($limit)
            ->order('id', 'desc')
            ->select()
            ->toArray();

        return $positions;
    }

    /**
     * 获取职位统计信息
     * @return array
     */
    public function getPositionStats(): array
    {
        $stats = [
            'total' => Db::name('position')->where('status', '>', 0)->count(),
            'active' => Db::name('position')->where('status', 1)->count(),
            'inactive' => Db::name('position')->where('status', 0)->count(),
            'deleted' => Db::name('position')->where('status', -1)->count()
        ];

        // 获取各职位下的员工数量统计
        $positionStats = Db::name('position')
            ->alias('p')
            ->field('p.id, p.title, COUNT(a.id) as user_count')
            ->leftJoin('admin a', 'p.id = a.position_id AND a.status >= 0')
            ->where('p.status', '>', 0)
            ->group('p.id')
            ->select()
            ->toArray();

        $stats['position_stats'] = $positionStats;

        return $stats;
    }
}
